package edu.zueb.sport.rest;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import edu.zueb.sport.dao.UserMapper;
import edu.zueb.sport.entity.User;
import edu.zueb.sport.enums.UserStatusEnum;
import edu.zueb.sport.exception.RestException;
import edu.zueb.sport.rest.api.AuthVO;
import edu.zueb.sport.rest.api.LoginRequest;
import edu.zueb.sport.rest.api.RestResponse;
import edu.zueb.sport.utils.JsonUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author jasonfu
 * @date 2024/9/11 14:14
 */
@Tag(name = "用户模块", description = "服务检测")
@Slf4j
@RestController
@RequestMapping(AuthRestController.PATH_AUTH)
public class AuthRestController {

    public static final String PATH_AUTH = "/api/auth";

    @Autowired
    UserMapper userMapper;

    /**
     * 这里直接使用本地的缓存，实际生产中可以采用 Redis 等分布式缓存
     */
    public static final Cache<String, User> TOKEN_CACHE = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(1, TimeUnit.HOURS)
            .build();

    @PostMapping(value = "/login")
    public RestResponse<AuthVO> login(@RequestBody LoginRequest loginRequest) {
        log.info("loginRequest={}", JsonUtils.toJson(loginRequest));
        String username = loginRequest.getUsername();
        User user = userMapper.getByUsername(username);
        if (user == null) {
            throw new RestException("用户名不存在");
        }
        log.info("user={}", JsonUtils.toJson(user));
        if (UserStatusEnum.DISABLED.match(user.getUserStatus())) {
            throw new RestException("用户已被禁用");
        }
        String password = loginRequest.getPassword();
        if (!StringUtils.equals(password, user.getPassword())) {
            throw new RestException("密码错误");
        }
        // 登录成功，生成一个 TOKEN，并将 TOKEN 放入缓存，跟当前用户名绑定
        AuthVO vo = new AuthVO();
        vo.setUsername(user.getUsername());
        vo.setUserId(user.getUserId());
        vo.setUserType(user.getUserType());
        String token = UUID.randomUUID().toString().replaceAll("-", StringUtils.EMPTY);
        vo.setToken(token);
        TOKEN_CACHE.put(token, user);
        return RestResponse.success(vo);
    }

    @PostMapping(value = "/logout")
    public RestResponse<Void> logout(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        TOKEN_CACHE.invalidate(token);
        return RestResponse.success(null);
    }
}
